/*
 * Copyright (C) 2008 ProSyst Software GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.modulefusion.testrunner;

import junit.framework.JUnit4TestAdapter;
import junit.framework.TestResult;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;

public class Activator implements BundleActivator {

	private BundleContext context;

	public void start(final BundleContext context) throws Exception {
		this.context = context;
		Thread t = new Thread(new Runnable() {
			public void run() {
				waitForAllBundles();
				runTests();
			}
		});
		t.start();
	}

	public void stop(BundleContext context) throws Exception {
	}

	private void waitForAllBundles() {
		if (!allBundlesAreActive())
			System.out.println("TestRunner: Not all bundles are active. Waiting ...");

		while (!allBundlesAreActive()) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
		System.out.println("TestRunner: All bundles are active.");
	}

	private boolean allBundlesAreActive() {
		Bundle[] bundles = context.getBundles();
		for (Bundle bundle : bundles) {
			if (bundle.getBundleId() == context.getBundle().getBundleId())
				continue;
			if (bundle.getState() != Bundle.ACTIVE)
				return false;
		}
		return true;
	}

	private void runTests() {
		TestResult result = new TestResult();
		ServiceReference[] refs;
		try {
			refs = context.getServiceReferences(TestRegistration.class.getName(), null);
		} catch (InvalidSyntaxException e) {
			throw new RuntimeException(e);
		}
		if (refs == null) {
			System.out.println("----------------------------------------------------");
			System.out.println("No tests found!");
			System.out.println("----------------------------------------------------");
			SystemUtil.exit(false);
		} else {
			for (ServiceReference ref : refs) {
				TestRegistration test = (TestRegistration) context.getService(ref);
				runTest(test, ref, result);
			}
			if (result.wasSuccessful()) {
				System.out.println("----------------------------------------------------");
				System.out.println("Tests SUCCESSFUL");
				System.out.println("----------------------------------------------------");
			}
			SystemUtil.exit(false);
		}
	}

	private void runTest(TestRegistration test, ServiceReference reference, TestResult result) {
		System.out.println("----------------------------------------------------");
		System.out.println("Running test [" + test.getTestClazz().getName() + "] from bundle ["
				+ reference.getBundle().getSymbolicName() + "]");
		System.out.println("----------------------------------------------------");

		JUnit4TestAdapter ta = new JUnit4TestAdapter(test.getTestClazz());
		result.addListener(new Listener(context));
		ta.run(result);
	}
}
